/**
 * 
 */
package com.zxc.httpclient;

import org.apache.http.HeaderElement;
import org.apache.http.HeaderElementIterator;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.entity.HttpEntityWrapper;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeaderElementIterator;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;

/**
 * @author Administrator
 *
 */
public class HttpClientConnectionPoolDemo {
	
	private static final int CONNECTION_TIMEOUT = 2 * 1000; //设置请求超时2秒钟 根据业务调整
	
	private static final int SO_TIMEOUT = 2 * 1000; //设置等待数据超时时间2秒钟 根据业务调整
	
	
	
	private static final CredentialsProvider credsProvider = new BasicCredentialsProvider();

	//httpClient
	private static final CloseableHttpClient httpClient;
	
	private static final RequestConfig reqestConfig;
	
	private static final ResponseHandler<String> responseHandler;
	
	static {
		System.setProperty("http.maxConnections","50");
	    System.setProperty("http.keepAlive", "true");
	    
	    // 创建连接池管理器
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
        // 设置最大连接数
        connectionManager.setMaxTotal(100);
        // 设置每个路由的最大连接数
        connectionManager.setDefaultMaxPerRoute(20);
        // 多长时间验证下连接是否正常
        connectionManager.setValidateAfterInactivity(60 * 1000);
	    // 或者定时检查空闲线程
//        connectionManager.closeIdleConnections(60*1000, TimeUnit.MILLISECONDS);
        
	    //设置basic校验
	    credsProvider.setCredentials(
	            new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM),
	            new UsernamePasswordCredentials("", ""));
	    
		ConnectionKeepAliveStrategy keepAliveStrategy = new ConnectionKeepAliveStrategy() {

			@Override
			public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
				HeaderElementIterator it = new BasicHeaderElementIterator(
						response.headerIterator(HTTP.CONN_KEEP_ALIVE));
				while (it.hasNext()) {
					HeaderElement he = it.nextElement();
					String param = he.getName();
					String value = he.getValue();
					if (value != null && param.equalsIgnoreCase("timeout")) {
						return Long.parseLong(value) * 1000;
					}
				}
				return 60 * 1000;// 如果没有约定，则默认定义时长为60s
			}
		};
	    
	    //创建http客户端
	    httpClient = HttpClients.custom()
	            .useSystemProperties()
	            .setRetryHandler(new DefaultHttpRequestRetryHandler(3,true))
	            .setDefaultCredentialsProvider(credsProvider)
	            .setConnectionManager(connectionManager)
	            .setKeepAliveStrategy(keepAliveStrategy)
	            .build();
	    
	    //初始化HTTP请求配置
	    reqestConfig = RequestConfig.custom()
	            .setContentCompressionEnabled(true)
	            .setSocketTimeout(SO_TIMEOUT)
	            .setAuthenticationEnabled(true)
	            .setConnectionRequestTimeout(CONNECTION_TIMEOUT)
	            .setConnectTimeout(CONNECTION_TIMEOUT)
	            .build();
	    
	    //初始化response解析器
	    responseHandler = new BasicResponseHandler();
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		doPost();
	}

	public static void doPost() {
        try {
        	HttpPost httpPost = new HttpPost("http://114.116.46.22:53081/tripQuery/query");
        	httpPost.setConfig(reqestConfig);
        	
        	String json = "{\r\n" + 
        			"	\"cabinGrades\":[],\r\n" + 
        			"    \"adultNum\": 1,\r\n" + 
        			"    \"adultNumber\": 1,\r\n" + 
        			"    \"childNum\": 0,\r\n" + 
        			"    \"childNumber\": 0,\r\n" + 
        			"    \"cid\": \"alitriptsyagodays20250313\",\r\n" + 
        			"    \"userName\": \"alitriptsyagodays20250313\",\r\n" + 
        			"    \"tripType\": 1,\r\n" + 
        			"    \"fromCity\": \"TPE\",\r\n" + 
        			"    \"toCity\": \"HKG\",\r\n" + 
        			"    \"fromDate\": \"20250505\",\r\n" + 
        			"    \"retDate\": \"\",\r\n" + 
        			"    \"skipCache\":1,\r\n" + 
        			"    \"test\": 0,\r\n" + 
        			"    \"debug\":0,\r\n" + 
        			"    \"source\":1\r\n" + 
        			"}";
        	StringEntity entity = new StringEntity(json);
        	httpPost.setEntity(entity);
        	
        	// 执行请求，获取响应
        	String responseContent = httpClient.execute(httpPost,responseHandler);
            System.out.println("Response content: " + responseContent);
        } catch (Exception e) {
            e.printStackTrace();
        }
	}
	
	public static void doGet() {
        try {
        	HttpGet httpGet = new HttpGet("https://www.baidu.com");
    	    httpGet.setConfig(reqestConfig);
    	    
        	// 执行请求，获取响应
        	String responseContent = httpClient.execute(httpGet,responseHandler);
            System.out.println("Response content: " + responseContent);
        } catch (Exception e) {
            e.printStackTrace();
        }
	}
}
